package com.example.hszpad.net;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import android.app.Activity;
import android.util.Log;

/**
 * Created by Administrator on 2017/4/21.
 */

public class SocketClient {
    private static final String TAG = "SocketClient";
    private String mIP;
    private int mPort;
    private Socket mSocket;
    private InputStream inputStream;
    private OutputStream outputStream;
    private Thread receiveThread;
    private Activity activity;

    public String getIP() {
        return mIP;
    }

    public void setIP(String IP) {
        this.mIP = IP;
    }

    public int getPort() {
        return mPort;
    }

    public void setPort(int Port) {
        this.mPort = Port;
    }

    public Socket getSocket() {
        return mSocket;
    }

    public SocketClient(Activity activity) {
        this.activity = activity;
    }

    public void close() {
        if (null != receiveThread) {
            receiveThread.interrupt();
            receiveThread = null;
        }
        if (null != mSocket) {
            if (!mSocket.isClosed()) {
                try {
                    mSocket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            mSocket = null;
        }
        if (null != inputStream) {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (null != outputStream) {
            try {
                outputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public boolean send(byte[] data) {
        Log.e(TAG, ProtocolPackageConvert.byteArrayToHexString(data));
        if (null != mSocket && mSocket.isConnected() && !mSocket.isClosed() && outputStream != null) {
            try {
                outputStream = mSocket.getOutputStream();
                outputStream.write(data);
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
                return false;
            }
        }
        return true;
    }

    public boolean send(ProtocolPackage p) {
        return send(ProtocolPackageConvert.convertProtocolPackageToByteArray(p));
    }

    public boolean conn() {
        close();
        try {
            mSocket = new Socket(mIP, mPort);
            mSocket.setKeepAlive(true);
            inputStream = mSocket.getInputStream();
            outputStream = mSocket.getOutputStream();
            if (receiveThread == null) {
                receiveThread = new Thread(new ReceiveRunnable(inputStream, activity));
                receiveThread.start();
            }
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }

    public class ReceiveRunnable implements Runnable {
        private InputStream inputStream;
        private Activity context;
        ProtocolPackage p = null;

        public ReceiveRunnable(InputStream inputStream, Activity activity) {
            this.inputStream = inputStream;
            this.context = activity;
        }

        @Override
        public void run() {
            int len = -1;
            byte[] buf = new byte[1024];
            while (true) {
                try {
                    while ((len = inputStream.read(buf, 0, buf.length)) != -1) {
                        p = ProtocolPackageConvert.convertByteArrayToProtocolPackage(buf);
                        if (null == p) {
                            if (context instanceof OnReceiveListener) {
                                context.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        ((OnReceiveListener) context).parseFail();
                                    }
                                });
                            }
                        } else {
                            if (context instanceof OnReceiveListener) {
                                context.runOnUiThread(new Runnable() {
                                    @Override
                                    public void run() {
                                        ((OnReceiveListener) context).receive(p);
                                    }
                                });
                            }
                        }
                    }
                } catch (final Exception e) {
                    e.printStackTrace();
                    if (context instanceof OnReceiveListener) {
                        context.runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                ((OnReceiveListener) context).catchException(e);
                            }
                        });
                    }
                }
            }
        }
    }

    public interface OnReceiveListener {

        void receive(ProtocolPackage p);

        void parseFail();

        void catchException(Exception e);
    }

    public boolean isRun() {
        if (null == mSocket || mSocket.isClosed() || !mSocket.isConnected()) {
            return false;
        }
        try {
            mSocket.sendUrgentData(0xFF);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return true;
        } catch (Exception se) {
            return false;
        }
    }
}
